using System;
using ValidationFramework.Extensions;
using System.Collections.Generic;
using System.Web.UI.WebControls;
using ValidationFramework.Reflection;

namespace ValidationFramework.Web.ASP
{
    public class RequiredRuleClientValidationGenerator : IClientValidationGenerator
    {
        /// <inheritdoc />
        public virtual IList<BaseValidator> CreateWebClientValidators(Rule rule, InfoDescriptor infoDescriptor)
        {
            var list = new List<BaseValidator>();
            var webValidator = new RequiredFieldWebValidatorEx();

            if ((bool) rule.GetPropertyValue("HasInitialValue"))
            {
                var initialValue = rule.GetPropertyValue("InitialValue");
                if (initialValue is DateTime)
                {
                    var initialValueAsDateTime = (DateTime)(object)initialValue;
                    if (initialValueAsDateTime.TimeOfDay == TimeSpan.Zero)
                    {
                        webValidator.InitialValue = initialValueAsDateTime.ToString("yyyy-MM-dd");
                    }
                    else
                    {
                        return null;
                    }
                }
                else
                {
                    webValidator.InitialValue = initialValue.ToString();
                }
                list.Add(webValidator);

                var isNullable = (bool) rule.GetPropertyValue("IsNullable");
                if (!isNullable)
                {
                    var notNullableWebValidator = new RequiredFieldWebValidatorEx();
                    list.Add(notNullableWebValidator);
                }
            }
            else
            {
                list.Add(webValidator);
            }
            var validationDataType = ValidatorCreatorHelper.GetValidationDataType(infoDescriptor.RuntimeTypeHandle);
            if (validationDataType.HasValue)
            {
                var validationDataTypeValue = validationDataType.Value;
                if (validationDataTypeValue != ValidationDataType.String)
                {
                    var compareValidator = new CompareValidator
                                                            {
                                                                Operator = ValidationCompareOperator.DataTypeCheck,
                                                                Type = validationDataTypeValue
                                                            };
                    list.Add(compareValidator);
                }
            }
            return list;
        }

        /// <inheritdoc />
        public bool CanHandleTarget(RuleContext ruleContext)
        {
            var rule = ruleContext.Rule;
            var type = rule.GetType();
            return type.IsGenericType && (type.GetGenericTypeDefinition() == typeof (RequiredRule<>)) && !(rule is RequiredStringRule);
        }
    }
}